// 1. 在配置文件中，使用的模块化规范是 commonjs 
const path = require('path')
// 1.1 引入编译html的插件
const HTMLWebpackPlugin = require('html-webpack-plugin')
// 1.2 引入抽离css文件的插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 1.3 用于代码检查的ESLint风格插件
const ESLintPlugin = require('eslint-webpack-plugin');
// 1.4 处理css压缩的功能插件
let CSSMinimizerWebpackPlugin, TersetWebpackPlugin;

// console.log(process.env.NODE_ENV);
// 获取模式
const mode = process.env.NODE_ENV;

if (mode === 'production') {
    CSSMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
    TersetWebpackPlugin = require('terser-webpack-plugin')
}

// 2. webpack的配置就是导出去一个对象
const options = {
    // 2.1 模式
    // development  开发模式      production  生产模式
    mode,

    // 2.2 入口模块的声明 - ./src/main.js
    entry: path.join(__dirname, 'src', 'main.js'),

    // 2.3 输出目录
    output: {
        // 2.3.1 在不同的系统路径分隔符不同，所以建议写成path模块的方法
        //   ./dist
        path: path.resolve(__dirname, 'dist'),
        //  ./js/bundle.js
        filename: './js/bundle-[contenthash:8].js',
        // 每次编译的时候把上一次的内容给清空
        clean: true
    },

    // 2.4 loader - 可以让webpack解析非js的其他模块
    module: {
        // 2.4.1 解析规则
        rules: [
            // 2.4.2 每一个非js的模块规则，都是一个对象
            // 处理css
            {
                // 匹配对应的文件
                test: /\.css$/,
                // 使用的 loader - loader 的解析顺序是 从右往左
                // use: ['style-loader', 'css-loader']
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader'
                ]
            },

            // 处理less
            {
                // 匹配对应的文件
                test: /\.less$/,
                // use: ['style-loader', 'css-loader', 'less-loader']
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                    'less-loader'
                ]
            },

            // 处理js - es6 转 es5 ，还得添加浏览器支持情况
            {
                test: /\.js$/,
                // 排除项 - 也是正则
                exclude: /node_modules/,
                // 使用的loader - 如果是配置项，则写成对象
                use: {
                    // 指定loader
                    loader: 'babel-loader',
                    // 其他选项
                    // options: {
                    //     // 选择预设处理es6的方式
                    //     presets: ['@babel/preset-env'],
                    //     // 有可能有其他插件，关于js的，没有就不写
                    //     // plugin: []
                    // }

                    // 更好的在其他的浏览器兼容es6高级语法
                    options: {
                        // 预设方案和细节声明 - 二维数组
                        presets: [
                            [
                                '@babel/preset-env',
                                {
                                    // 只打包使用的ES6新API的实现代码
                                    useBuiltIns: 'usage',
                                    // 指定core-js的版本号为2
                                    corejs: { version: 2 }
                                }
                            ]
                        ],
                        // 可用插件声明
                        // plugins: []
                    }
                }
            },

            // 背景图片
            {
                // 指定匹配的文件后缀名
                test: /\.(jpg|jpeg|png|gif|bmp|webp)$/,
                // 类型为资源
                type: 'asset',
                // 转换方式
                parser: {
                    // 指定最大的base64格式的临界值
                    dataUrlCondition: {
                        maxSize: 5 * 1024
                    }
                },
                // 生成的指定路径
                generator: {
                    // [hash:8] - 随机生成8位的字符 - 防止名称冲突
                    filename: './imgs/[name]-[hash:6][ext]'
                }
            },

            // 插入图片
            {
                test: /\.html$/,
                use: {
                    loader: 'html-loader'
                }
            },

            // 处理字体图标
            {
                // 指定匹配的文件后缀名
                test: /\.(ttf|svg|woff|woff2)$/,
                // 类型为资源
                type: 'asset',
                // 转换方式
                parser: {
                    // 指定最大的base64格式的临界值
                    dataUrlCondition: {
                        maxSize: 5 * 1024
                    }
                },
                // 生成的指定路径
                generator: {
                    // [hash:8] - 随机生成8位的字符 - 防止名称冲突
                    filename: './fonts/[hash:8][ext]'
                }
            },
        ]
    },

    // 2.5 plugin 插件 复数加s
    plugins: [
        // 2.5.1 编译html的插件
        new HTMLWebpackPlugin({
            // 指定模板存放的路径
            template: './public/index.html',
            // 在body中注入编译好的文件
            inject: "body",
            // 每一次编译的bundle.js 带一些哈希，防止缓存
            hash: true,
            // 关于html的压缩处理
            minify: {
                // 移除属性中的双引号
                removeAttributeQuotes: true,
                // 移除注释
                removeComments: true,
                // 去除换行和空格
                collapseWhitespace: true
            }
        }),

        // 2.5.2 抽离css的插件
        new MiniCssExtractPlugin({
            filename: './css/[hash:5].css'
        })
    ]
}

// 判断模式进入操作
if (mode === 'development') {
    // 2.5.3 注册 ESLint 插件的实例
    options.plugins.push(new ESLintPlugin())
    // 2.6 在 开发阶段 ，需要使用虚拟服务的方式临时编译
    options.devServer = {
        // 自动打开
        open: true,
        port: 8080
    }
    // 2.7 在 开发阶段，会开启代码调试，具体定位到指定的行号
    options.devtool = 'cheap-module-source-map'
} else if (mode === 'production') {
    // 2.8 额外配置压缩的插件
    // 如果要单独处理css的压缩，那么js的自动压缩也会失效
    options.optimization = {
        minimizer: [
            new CSSMinimizerWebpackPlugin(),
            new TersetWebpackPlugin()
        ]
    }
}

module.exports = options